// SPDX-FileCopyrightText: Copyright 2025-2025 深圳市同心圆网络有限公司
// SPDX-License-Identifier: GPL-3.0-only

package trace_api_impl

import (
	"context"

	"gitcode.com/opendragonfly/df_proto_gen_go.git/trace_api"
	"gitcode.com/opendragonfly/df_server/config"
	"gitcode.com/opendragonfly/df_server/dao/member_dao"
	"gitcode.com/opendragonfly/df_server/dao/trace_dao"
	"github.com/dgraph-io/badger/v4"
)

type TraceApiImpl struct {
	trace_api.UnimplementedTraceApiServer
}

func (apiImpl *TraceApiImpl) ListService(ctx context.Context, req *trace_api.ListServiceRequest) (*trace_api.ListServiceResponse, error) {
	emptyList := []*trace_api.ServiceInfo{}

	cfg, err := config.ReadServerConfigFromCache()
	if err != nil {
		return nil, err
	}

	if cfg.SuperToken != "" && req.AccessToken == cfg.SuperToken {
		//do nothing
	} else {
		remoteCfg, ok := cfg.GetRemote(req.RemoteId)
		if !ok {
			return &trace_api.ListServiceResponse{
				Code:        trace_api.ListServiceResponse_CODE_NO_REMOTE,
				ErrMsg:      "鉴权服务器不存在",
				ServiceList: emptyList,
			}, nil
		}
		_, _, err = member_dao.QueryMember(ctx, remoteCfg.RemoteAddr, req.AccessToken)
		if err != nil {
			return &trace_api.ListServiceResponse{
				Code:        trace_api.ListServiceResponse_CODE_NO_PERMISSION,
				ErrMsg:      "用户不存在",
				ServiceList: emptyList,
			}, nil
		}
	}

	serviceList, err := trace_dao.TraceDao.ListService(req.FromTime, req.ToTime)
	if err != nil {
		return nil, err
	}

	return &trace_api.ListServiceResponse{
		Code:        trace_api.ListServiceResponse_CODE_OK,
		ServiceList: serviceList,
	}, nil
}

func (apiImpl *TraceApiImpl) ListRootSpanName(ctx context.Context, req *trace_api.ListRootSpanNameRequest) (*trace_api.ListRootSpanNameResponse, error) {
	emptyList := []string{}

	cfg, err := config.ReadServerConfigFromCache()
	if err != nil {
		return nil, err
	}

	if cfg.SuperToken != "" && req.AccessToken == cfg.SuperToken {
		//do nothing
	} else {
		remoteCfg, ok := cfg.GetRemote(req.RemoteId)
		if !ok {
			return &trace_api.ListRootSpanNameResponse{
				Code:     trace_api.ListRootSpanNameResponse_CODE_NO_REMOTE,
				ErrMsg:   "鉴权服务器不存在",
				NameList: emptyList,
			}, nil
		}
		_, _, err = member_dao.QueryMember(ctx, remoteCfg.RemoteAddr, req.AccessToken)
		if err != nil {
			return &trace_api.ListRootSpanNameResponse{
				Code:     trace_api.ListRootSpanNameResponse_CODE_NO_PERMISSION,
				ErrMsg:   "用户不存在",
				NameList: emptyList,
			}, nil
		}
	}

	nameList, err := trace_dao.TraceDao.ListRootName(req.Service, req.FromTime, req.ToTime)
	if err != nil {
		return nil, err
	}
	return &trace_api.ListRootSpanNameResponse{
		Code:     trace_api.ListRootSpanNameResponse_CODE_OK,
		NameList: nameList,
	}, nil
}

func (apiImpl *TraceApiImpl) ListTrace(ctx context.Context, req *trace_api.ListTraceRequest) (*trace_api.ListTraceResponse, error) {
	emptyList := []*trace_api.TraceInfo{}

	cfg, err := config.ReadServerConfigFromCache()
	if err != nil {
		return nil, err
	}
	if cfg.SuperToken != "" && req.AccessToken == cfg.SuperToken {
		//do nothing
	} else {
		remoteCfg, ok := cfg.GetRemote(req.RemoteId)
		if !ok {
			return &trace_api.ListTraceResponse{
				Code:      trace_api.ListTraceResponse_CODE_NO_REMOTE,
				ErrMsg:    "鉴权服务器不存在",
				TraceList: emptyList,
			}, nil
		}
		_, _, err = member_dao.QueryMember(ctx, remoteCfg.RemoteAddr, req.AccessToken)
		if err != nil {
			return &trace_api.ListTraceResponse{
				Code:      trace_api.ListTraceResponse_CODE_NO_PERMISSION,
				ErrMsg:    "用户不存在",
				TraceList: emptyList,
			}, nil
		}
	}

	traceList := []*trace_api.TraceInfo{}

	if req.SortBy == trace_api.SORT_BY_SORT_BY_CONSUME_TIME {
		traceList, err = trace_dao.TraceDao.ListTraceByConsumeTime(req.Service, req.FilterByRootSpanName, req.RootSpanName, req.FromTime, req.ToTime, req.Limit)
		if err != nil {
			return nil, err
		}
	} else if req.SortBy == trace_api.SORT_BY_SORT_BY_START_TIME {
		traceList, err = trace_dao.TraceDao.ListTraceByStartTime(req.Service, req.FilterByRootSpanName, req.RootSpanName, req.FromTime, req.ToTime, req.Limit)
		if err != nil {
			return nil, err
		}
	}
	return &trace_api.ListTraceResponse{
		Code:      trace_api.ListTraceResponse_CODE_OK,
		TraceList: traceList,
	}, nil
}

func (apiImpl *TraceApiImpl) GetTrace(ctx context.Context, req *trace_api.GetTraceRequest) (*trace_api.GetTraceResponse, error) {
	emptyInfo := &trace_api.TraceInfo{
		Service: &trace_api.ServiceInfo{},
		RootSpan: &trace_api.SpanInfo{
			AttrList:  []*trace_api.AttrInfo{},
			EventList: []*trace_api.EventInfo{},
		},
	}

	cfg, err := config.ReadServerConfigFromCache()
	if err != nil {
		return nil, err
	}

	if cfg.SuperToken != "" && req.AccessToken == cfg.SuperToken {
		//do nothing
	} else {
		remoteCfg, ok := cfg.GetRemote(req.RemoteId)
		if !ok {
			return &trace_api.GetTraceResponse{
				Code:   trace_api.GetTraceResponse_CODE_NO_REMOTE,
				ErrMsg: "鉴权服务器不存在",
				Trace:  emptyInfo,
			}, nil
		}
		_, _, err = member_dao.QueryMember(ctx, remoteCfg.RemoteAddr, req.AccessToken)
		if err != nil {
			return &trace_api.GetTraceResponse{
				Code:   trace_api.GetTraceResponse_CODE_NO_PERMISSION,
				ErrMsg: "用户不存在",
				Trace:  emptyInfo,
			}, nil
		}
	}

	traceList, err := trace_dao.TraceDao.ListTraceById(req.Service, []string{req.TraceId})
	if err != nil {
		return nil, err
	}
	if len(traceList) != 1 {
		return &trace_api.GetTraceResponse{
			Code:   trace_api.GetTraceResponse_CODE_NO_TRACE,
			ErrMsg: "链路追踪记录不存在",
			Trace:  emptyInfo,
		}, nil
	}
	return &trace_api.GetTraceResponse{
		Code:  trace_api.GetTraceResponse_CODE_OK,
		Trace: traceList[0],
	}, nil
}

func (apiImpl *TraceApiImpl) ListSpan(ctx context.Context, req *trace_api.ListSpanRequest) (*trace_api.ListSpanResponse, error) {
	emptyList := []*trace_api.SpanInfo{}

	cfg, err := config.ReadServerConfigFromCache()
	if err != nil {
		return nil, err
	}

	if cfg.SuperToken != "" && req.AccessToken == cfg.SuperToken {
		//do nothing
	} else {
		remoteCfg, ok := cfg.GetRemote(req.RemoteId)
		if !ok {
			return &trace_api.ListSpanResponse{
				Code:     trace_api.ListSpanResponse_CODE_NO_REMOTE,
				ErrMsg:   "鉴权服务器不存在",
				SpanList: emptyList,
			}, nil
		}
		_, _, err = member_dao.QueryMember(ctx, remoteCfg.RemoteAddr, req.AccessToken)
		if err != nil {
			return &trace_api.ListSpanResponse{
				Code:     trace_api.ListSpanResponse_CODE_NO_PERMISSION,
				ErrMsg:   "用户不存在",
				SpanList: emptyList,
			}, nil
		}
	}

	fullTrace, err := trace_dao.TraceDao.GetFullTrace(req.Service, req.TraceId)
	if err != nil {
		if err == badger.ErrKeyNotFound {
			return &trace_api.ListSpanResponse{
				Code:     trace_api.ListSpanResponse_CODE_NO_TRACE,
				ErrMsg:   "链路追踪记录不存在",
				SpanList: emptyList,
			}, nil
		}
		return nil, err
	}

	return &trace_api.ListSpanResponse{
		Code:     trace_api.ListSpanResponse_CODE_OK,
		SpanList: fullTrace.SpanList,
	}, nil
}
